/*
    message 格式定义:
        {type: 'mine', uid:, name:, time:, atkgold:, defgold:, succ:, replay:, flag:, full:}
        {type: 'rank', uid:, name:, time:, rank:, succ:, replay:, flag:}
        {type: 'prison', uid:, name:, time:, replay:}
        {type: 'chat', uid:, name:, time:, content:}
        {type: 'combine', name: uid:, time:, robbed:, lost: }
        {type: 'league_war', name: uid:, time:, succ:, energy: score: replay: }
        {type: 'friend', name: uid:, time:, agree:, apply: }
*/

var tail = new List();      // 消息尾部标记

function Message(){
    this.users = {}; /* uid : {
                            messages:[] // 消息队列
                            unread: 0   // 未读取的最新消息的条数
                            im:0        // 实时聊天最后拉取数据
                            headline:0  // 跑马灯最后拉取数据
                            champsbattle:0 //王者战场最后拉取数据
                            prison:0    // 监狱抓捕消息更新
                            league:0    // 军团最后拉取数据
                            friend:0,   // 好友消息更新
                        }*/
    this.imHead = new List();           // 实时聊天消息List({uid:,name:,content})头
    this.imTail = this.imHead;          // 实时聊天消息尾部
    this.imCount = 0;                   // 实时聊天消息长途 
    this.headlineHead = new List();     // 跑马灯数据List({uid:,name:,content})头
    this.headlineTail = this.headlineHead;// 跑马灯数据List({uid:,name:,content})头
    this.headlineCount = 0;             // 跑马灯消息长度
    this.leaguetalks = {                // 军团内部聊天
        /* 'name' : {                   // 军团名字
                'leaguetalkHead':       // 军团聊天消息List({uid:,name:,content})头
                'leaguetalkTail':       // 军团聊天消息尾部 
                'leaguetalkCount':      // 军团聊天消息长度
        }*/ 
    };

    this.champsbattleHead = new List();     
    this.champsbattleTail = this.champsbattleHead;
    this.champsbattleCount = 0;
}

Message.prototype = {

    getUser : function(uid) {
        var user = this.users[uid];
        if( !user ) {
            user = {
                'messages' : [], 
                'unread' : 0,
                'im' : this.imHead,
                'headline' : this.headlineHead,
                'champsbattle': this.champsbattleHead,
                'prison' : 0,
                'league':0, 
                'friend':0,
            };
            this.users[uid] = user;
        }

        return user;
    },

    addMessage : function(uid, message){
        var userData = this.getUser(uid);
        var max = gConfGlobal.GlobalMessageMaxLength; // 消息队列最大长度
        
        if( userData.unread < max ) {
            userData.unread +=1;
        }

        var messages = userData.messages;
        if( messages.length >= max ) {
            var expireMessage = messages.shift(); 
            if( expireMessage.replay ) {
                gReplay.deleteReplay(expireMessage.replay);
            }
        }

        userData.messages.push(message);
    },

    addPrisonUpdate : function(uid, update) {
        var userData = this.getUser(uid);
        userData.prison = update;
    },

    addIM : function(uid, name, content, gentry) {
        var im = new List({uid:uid, name:name, content:content, gentry: gentry});
        this.imTail.next = im;
        this.imTail = im;

        if( this.imCount >= 50 ) {
            var head = this.imHead;
            this.imHead = head.next;
            head.next = tail;
        }

        if( this.imCount < 50 ) {
            this.imCount += 1;
        }
    },

    addHeadline : function(uid, name, content, gentry, key) {
        var obj = {uid:uid, name:name, content:content, gentry: gentry};
        if( key ) {
            obj.key = key;
        }
        var headline = new List(obj);
        this.headlineTail.next = headline;
        this.headlineTail = headline;

        if( this.headlineCount >= 50 ) {
            var head = this.headlineHead;
            this.headlineHead = head.next;
            head.next = tail;
        }

        if( this.headlineCount < 50 ) {
            this.headlineCount += 1;
        }
    },

    addSystemMessage : function(key, content) {
        this.addHeadline(0, '', content, 0, key);
    },

    addLeaguetalk : function(uid, name, content, leagueName, gentry) {
        if( !(leagueName in this.leaguetalks) ) {
            var list = new List();
            this.leaguetalks[leagueName] = {
                'leaguetalkHead' : list,
                'leaguetalkTail' : list,
                'leaguetalkCount' : 0,
            }; 
        } 

        var talk = new List({uid:uid, name:name, content:content, gentry: gentry}); 
        var leaguetalk = this.leaguetalks[leagueName];
        leaguetalk.leaguetalkTail.next = talk;
        leaguetalk.leaguetalkTail = talk;

        if( leaguetalk.leaguetalkCount >= 20 ) {
            var head = leaguetalk.leaguetalkHead; 
            leaguetalk.leaguetalkHead = head.next;
            head.next = tail;
        }

        if( leaguetalk.leaguetalkCount < 20 ) {
            leaguetalk.leaguetalkCount += 1; 
        }
    },

    addChampsbattleChat: function(uid, name, content, gentry, key) {
        var obj = {uid:uid, name:name, content:content, gentry: gentry};

        var message = new List(obj);
        this.champsbattleTail.next = message;
        this.champsbattleTail = message;

        if( this.champsbattleCount >= 20 ) {
            var head = this.champsbattleHead;
            this.champsbattleHead = head.next;
            head.next = tail;
        }

        if( this.champsbattleCount < 20 ) {
            this.champsbattleCount += 1;
        }
    },

    getPrisonUpdate : function(uid) {
        var userData = this.getUser(uid);
        var update = null;
        if( userData.prison ) {
            update = userData.prison;
            userData.prison = 0;
        }

        return update;
    },

    getMessage : function(uid, all){
        var userData = this.getUser(uid);
        var messages = [];
        if( all ) {
            messages = userData.messages;
        }else{
            var len = userData.messages.length;
            var start = len - userData.unread;
            messages = userData.messages.slice(start, len);
        }
        
        userData.unread = 0;

        var friendMessages = this.getFriendApllyMessage(uid, all);
        messages = messages.concat(friendMessages);

        return messages;
    },

    getIM : function(uid) {
        var userData = this.getUser(uid);
        // 数据读取游标已经不在队列
        if( userData.im.next == tail ) {
            userData.im = this.imHead;
        }

        var ims = [];
        
        var item = userData.im;
        for( var i=0; i<30 && item.next; i++ ) {
            if( item.next.obj.uid != uid ) {
                ims.push(item.next.obj);
            }
            item = item.next;
        }
        userData.im = item;

        return ims;
    },

    getHeadline : function(uid) {
        var userData = this.getUser(uid);
        if( userData.headline.next == tail ) {
            userData.headline = this.headlineHead;
        }

        var headlines = [];

        var item = userData.headline;
        for( var i=0; i<30 && item.next; i++ ) {
            if( item.next.obj.uid != uid ) {
                headlines.push(item.next.obj);
            }
            item = item.next;
        }

        userData.headline = item;

        return headlines;
    },

    getLeaguetalk : function(uid, leagueName) {
        var talks = [];
        if( !(leagueName in this.leaguetalks) ) {
            return  talks;
        }

        var userData = this.getUser(uid); 
        var leaguetalk = this.leaguetalks[leagueName];
        if( !userData.league || userData.league.next == tail ) {
           userData.league = leaguetalk.leaguetalkHead; 
        }

        var item = userData.league;
        for( var i=0; i<20 && item.next; i++ ) {
            if( item.next.obj.uid != uid ) {
                talks.push(item.next.obj);
            }
            item = item.next;
        }

        userData.league = item;
        return talks;
    },

    getChampsBattleChat: function(uid) {
        var userData = this.getUser(uid);
        if( userData.champsbattle.next == tail ) {
            userData.champsbattle = this.champsbattleHead;
        }

        var champsbattles = [];

        var item = userData.champsbattle;
        for (var i = 0; i < 20 && item.next; ++i) {
            if (item.next.obj.uid != uid) {
                champsbattles.push(item.next.obj);
            }
            item = item.next;
        }

        userData.champsbattle = item;

        return champsbattles;
    },

    resetLeaguetalk :  function(uid) {
        var userData = this.getUser(uid);
        userData.league = 0;
    },

    setFriendUpdate : function(uid) {
        var userData = this.getUser(uid);
        userData.friend = true;
    },

    getFriendApllyMessage : function(uid, all) {
        var userData = this.getUser(uid);
        var messages = [];
        if( !userData.friend && !all ) return messages;
        var friendApplied = gFriend.getUser(uid).applied; 
        for( var id in friendApplied ) {
            var friendInfo = gUserInfo.getUser(id);
            messages.push({
                'type' : 'friend',
                'name' : friendInfo.name,
                'uid' : id,
                'time' : friendApplied[id],
                'agree' :0, 
                'apply' :1,
            });
        }
        userData.friend = false;
        return messages;
    },

}

exports.get = function(req, resp, onHandled) {
    resp.nolog = 1;
    do {
        resp.data.messages = gMessage.getMessage(req.uid, req.args.all);

        var prisonUpdate = gMessage.getPrisonUpdate(req.uid);
        if( prisonUpdate ) {
            resp.data.prison = prisonUpdate;
        }

        if( req.args.league ) {
            resp.data.leaguetalks = gMessage.getLeaguetalk(req.uid, req.args.league); 
        }

        resp.data.ims = gMessage.getIM(req.uid);
        resp.data.headlines = gMessage.getHeadline(req.uid);
        resp.data.champsbattle = gMessage.getChampsBattleChat(req.uid);
    } while(false);

    onHandled();
}

exports.im = function(req, resp, onHandled) {
    resp.nolog = 1;
    do {
        if( req.args.name && req.args.content ) {
            gMessage.addIM(req.uid, req.args.name, req.args.content, req.args.gentry);
        }

    } while(false);

    onHandled();
}

exports.headline = function(req, resp, onHandled) {
    resp.nolog = 1;
    do {
        if( req.args.name && req.args.content ) {
            gMessage.addHeadline(req.uid, req.args.name, req.args.content, req.args.gentry);
        }
    } while(false);

    onHandled();
}

exports.leaguetalk = function(req, resp, onHandled) {
    resp.nolog = 1;
    do {
        if( !req.args.league ) {
            resp.code = 1; resp.desc = 'invalid'; break;
        }
        
        if( req.args.name && req.args.content ) {
            gMessage.addLeaguetalk(req.uid, req.args.name, req.args.content, req.args.league, req.args.gentry);
        }
    } while(false);

    onHandled();
}

exports.chat = function(req, resp, onHandled) {
    resp.nolog = 1;
    do {
        var userInfo = gUserInfo.getUser(req.args.uid);
        if( userInfo ) {
            var message = {
                'type': 'chat', 
                'uid': req.uid,
                'name': gUserInfo.getUser(req.uid).name,
                'time': common.getTime(),
                'content': req.args.content,
                'gentry':  req.args.gentry,
            };
            gMessage.addMessage(req.args.uid, message);
        }
        
    } while(false);

    onHandled();
}

exports.champsbattle_chat = function(req, resp, onHandled) {
    resp.nolog = 1;
    do {
        if (req.args.name && req.args.content) {
            gMessage.addChampsbattleChat(req.uid, req.args.name, req.args.content, req.args.gentry);
        }
    } while(false);

    onHandled();
}

exports.Message = Message;
